package com.xinda.xiaoxing.util;

import org.springframework.util.CollectionUtils;

import java.util.*;

public class MapUtil {

    /**
     * 将map切成段
     *
     * @param chunkMap 被切段的map
     * @param divisionNum 分成的份数
     * @param <k>      map的key类型
     * @param <v>      map的value类型 如果是自定义类型，则必须实现equals和hashCode方法
     * @return
     */
    public static <k, v> List<Map<k, v>> mapChunkByDivisionNum(Map<k,v> chunkMap,int divisionNum){
        if(divisionNum>chunkMap.size()){
            divisionNum=chunkMap.size();
        }

        int chunkNum=(int)Math.round(chunkMap.size()*1.0/divisionNum);
        List<Map<k, v>> maps = mapChunkByChunkNum(chunkMap, chunkNum);

        int size=maps.size();
        if(size>divisionNum){
            Map<k, v> lastMap=maps.get(size-1);
            Map<k, v> secondToLastMap = maps.get(size - 2);
            secondToLastMap.putAll(lastMap);
            maps.remove(size-1);
        }

        return maps;
    }



    /**
     * 将map切成段，作用与PHP的array_chunk函数相当
     *
     * @param chunkMap 被切段的map
     * @param chunkNum 每段的大小
     * @param <k>      map的key类型
     * @param <v>      map的value类型 如果是自定义类型，则必须实现equals和hashCode方法
     * @return
     */
    public static <k, v> List<Map<k, v>> mapChunkByChunkNum(Map<k, v> chunkMap, int chunkNum) {
        if (chunkMap == null || chunkNum <= 0) {
            List<Map<k, v>> list = new ArrayList<>();
            list.add(chunkMap);
            return list;
        }
        Set<k> keySet = chunkMap.keySet();
        Iterator<k> iterator = keySet.iterator();
        int i = 1;
        List<Map<k, v>> total = new ArrayList<>();
        Map<k, v> tem = new HashMap<>();
        while (iterator.hasNext()) {
            k next = iterator.next();
            tem.put(next, chunkMap.get(next));
            if (i == chunkNum) {
                total.add(tem);
                tem = new HashMap<>();
                i = 0;
            }
            i++;
        }
        if (!CollectionUtils.isEmpty(tem)) {
            total.add(tem);
        }
        return total;
    }

}
